﻿using System;
using System.Collections.Generic;
using YJKGridTopologyCal.Geometries;

namespace YJKGridTopologyCal.Noding
{
	public class SegmentStringDissolver
	{
		public SegmentStringDissolver(SegmentStringDissolver.ISegmentStringMerger merger)
		{
			this._merger = merger;
		}

		public SegmentStringDissolver() : this(null)
		{
		}

		public void Dissolve(IEnumerable<ISegmentString> segStrings)
		{
			foreach (ISegmentString segString in segStrings)
			{
				this.Dissolve(segString);
			}
		}

		private void Add(OrientedCoordinateArray oca, ISegmentString segString)
		{
			this._ocaMap.Add(oca, segString);
		}

		public void Dissolve(ISegmentString segString)
		{
			OrientedCoordinateArray oca = new OrientedCoordinateArray(segString.Coordinates);
			ISegmentString segmentString = this.FindMatching(oca);
			if (segmentString == null)
			{
				this.Add(oca, segString);
				return;
			}
			if (this._merger != null)
			{
				bool isSameOrientation = CoordinateArrays.Equals(segmentString.Coordinates, segString.Coordinates);
				this._merger.Merge(segmentString, segString, isSameOrientation);
			}
		}

		private ISegmentString FindMatching(OrientedCoordinateArray oca)
		{
			ISegmentString result;
			if (this._ocaMap.TryGetValue(oca, out result))
			{
				return result;
			}
			return null;
		}

		public ICollection<ISegmentString> Dissolved
		{
			get
			{
				return this._ocaMap.Values;
			}
		}

		private readonly SegmentStringDissolver.ISegmentStringMerger _merger;

		private readonly IDictionary<OrientedCoordinateArray, ISegmentString> _ocaMap = new SortedDictionary<OrientedCoordinateArray, ISegmentString>();

		public interface ISegmentStringMerger
		{
			void Merge(ISegmentString mergeTarget, ISegmentString ssToMerge, bool isSameOrientation);
		}
	}
}
